import axios from "axios"
import type { AxiosInstance } from "axios" // 第三方内置的类型
import type { HYRequestInterceptors, HYRequestConfig } from "./type"
import { ElLoading } from "element-plus"
import { LoadingInstance } from "element-plus/lib/components/loading/src/loading"

const DEFAULT_LOADING = true

class HYRequest {
  instance: AxiosInstance
  interceptors?: HYRequestInterceptors
  showLoading: boolean
  loading?: LoadingInstance
  // 传入一些配置
  constructor(config: HYRequestConfig) {
    this.instance = axios.create(config)
    this.showLoading = config.showLoading ?? DEFAULT_LOADING
    this.interceptors = config.interceptors

    // 请求拦截器
    this.instance.interceptors.request.use(this.interceptors?.requestInterceptor, this.interceptors?.requestInterceptorCatch)
    // 响应拦截器
    this.instance.interceptors.response.use(this.interceptors?.responseInterceptor, this.interceptors?.responseInterceptoCatch)
    // 添加所有的实例都有的拦截器
    this.instance.interceptors.request.use(
      (config) => {
        if (this.showLoading) {
          this.loading = ElLoading.service({
            lock: true,
            text: "加载中。。。",
            background: "rgba(0,0,0,.3)"
          })
        }
        return config
      },
      (err) => {
        return err
      }
    )
    this.instance.interceptors.response.use(
      (res) => {
        this.loading?.close() // 移除lodaing
        const data = res.data
        if (data.returnCode === "-1001") {
          console.log("请求失败，  错误信息")
        } else {
          return data
        }
      },
      (err) => {
        this.loading?.close() // 移除lodaing
        if (err.response.status === 401) {
          console.log("请求错误 401")
        }
        return err
      }
    )
  }

  request<T>(config: HYRequestConfig<T>): Promise<T> {
    return new Promise((resolve, reject) => {
      // 配置单独的请求拦截
      if (config.interceptors?.requestInterceptor) {
        config = config.interceptors.requestInterceptor(config)
      }
      if (config.showLoading === false) {
        // 设置将传入的值复制给实例
        this.showLoading = config.showLoading
      }
      // 发送请求
      this.instance
        .request<any, T>(config)
        .then((res) => {
          // 配置单独请求的响应拦截
          if (config.interceptors?.responseInterceptor) {
            res = config.interceptors?.responseInterceptor(res)
          }
          this.showLoading = DEFAULT_LOADING
          resolve(res)
        })
        .catch((error) => {
          this.showLoading = DEFAULT_LOADING
          reject(error)
        })
    })
  }

  get<T>(config: HYRequestConfig<T>): Promise<T> {
    return this.request<T>({ ...config, method: "GET" })
  }
  post<T>(config: HYRequestConfig<T>): Promise<T> {
    return this.request<T>({ ...config, method: "POST" })
  }
}

export default HYRequest
